﻿using APILibrary.Attribute;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using TsInterfaceRazor.ModelInfo;

namespace TsInterfaceRazor.analysis
{
    public class ToTs
    {
        public static List<ModelDescribe> ModelDescribes=new List<ModelDescribe>();
        public static List<string> ClassNames = new List<string>();
        public static bool GetModelDescribes(Type type)
        {
            if (type.Name == "String" || type.Name=="Task`1")
            {
                return true;
            }
            var sRetrun = type.Name;
            ModelDescribe modelDescribe = new ModelDescribe();
            modelDescribe.ClassDescribe= GetDescribe(type);
            if (type.IsGenericType)
            {
                sRetrun = sRetrun.Replace("`1", "");

            }
            modelDescribe.ClassName = sRetrun;
            ClassNames.Add(modelDescribe.ClassName);
            List<ModelPropertyDescribe> modelPropertyDescribes = new List<ModelPropertyDescribe>();

            foreach (var k in type.GetProperties())
            {
                ModelPropertyDescribe modelPropertyDescribe = new ModelPropertyDescribe();

                modelPropertyDescribe.PropertyDescribe= GetDescribe(k);
                modelPropertyDescribe.PropertyName = k.Name;

                if (k.PropertyType.IsClass && k.PropertyType.Name !="String" && k.PropertyType.Name != "List`1")
                {//属性类型是类的话
                    if (!k.PropertyType.IsGenericType)
                    {
                        var name = k.PropertyType.Name;
                        modelPropertyDescribe.PropertyType = name;
                        var result = ModelDescribes.Any(e => e.ClassName == name);
                        if (!result)
                        {
                            if (ClassNames.Any(e => e.Contains(name)))
                            {
                                modelPropertyDescribes.Add(modelPropertyDescribe);
                                continue;
                            }
                            else
                            {
                                GetModelDescribes(k.PropertyType);
                            }
                            
                        }
                    }
                    else
                    {
                        var rootType = k.PropertyType.GetGenericArguments()[0];
                        var name = rootType.Name;
                        modelPropertyDescribe.PropertyType = name;
                        var result = ModelDescribes.Any(e => e.ClassName == name);
                        if (!result)
                        {
                            if (ClassNames.Any(e => e.Contains(name)))
                            {
                                modelPropertyDescribes.Add(modelPropertyDescribe);
                                continue;
                            }
                            else
                            {
                                GetModelDescribes(rootType);
                            }
                            
                        }
                    }
                    


                }
                else
                {
                    if (k.IsIEnumerableType() )
                    {//是否是IsIEnumerableType

                        var rootType = k.PropertyType.GetGenericArguments()[0];

                        if (rootType.IsClass && rootType.Name!="String")
                        {//如果是类的话
                            modelPropertyDescribe.PropertyType += "Array<";
                            modelPropertyDescribe.PropertyType += rootType.Name;
                            modelPropertyDescribe.PropertyType += ">";
                            var result = ModelDescribes.Any(e => e.ClassName == rootType.Name);
                            if (!result)
                            {
                                if (ClassNames.Any(e => e.Contains(rootType.Name)))
                                {
                                    modelPropertyDescribes.Add(modelPropertyDescribe);
                                    continue;
                                }
                                else
                                {
                                    GetModelDescribes(rootType);
                                }
                                //GetModelDescribes(rootType);
                            }
                        }
                        else
                        {
                            if (rootType.IsNullableType())
                            {
                                var rootType2 = rootType.GetGenericArguments()[0];
                                modelPropertyDescribe.PropertyType += "Array<";
                                modelPropertyDescribe.PropertyType += APILibrary.TypeDic.TypeDic.TsTypeDic[rootType2.ToString().Split('.')[rootType2.ToString().Split('.').Length - 1]];
                                //modelPropertyDescribe.PropertyType += "| null";
                                modelPropertyDescribe.IsNull = true;
                                modelPropertyDescribe.PropertyType += ">";
                            }
                            else
                            {
                                modelPropertyDescribe.PropertyType += "Array<";
                                modelPropertyDescribe.PropertyType += APILibrary.TypeDic.TypeDic.TsTypeDic[rootType.ToString().Split('.')[rootType.ToString().Split('.').Length - 1]];
                                modelPropertyDescribe.PropertyType += ">";
                                //if (k.IsNullableType())
                                //{
                                //    modelPropertyDescribe.PropertyType += "|| null";
                                //}
                            }
                        }


                    }
                    else
                    {
                        if (k.IsNullableType())
                        {
                            var rootType = k.PropertyType.GetGenericArguments()[0];
                            modelPropertyDescribe.PropertyType = APILibrary.TypeDic.TypeDic.TsTypeDic[rootType.ToString().Split('.')[rootType.ToString().Split('.').Length - 1]];
                            //modelPropertyDescribe.PropertyType += "| null";
                            modelPropertyDescribe.IsNull = true;
                        }
                        else
                        {
                            modelPropertyDescribe.PropertyType = APILibrary.TypeDic.TypeDic.TsTypeDic[k.PropertyType.Name.ToString().Split('.')[k.PropertyType.Name.ToString().Split('.').Length - 1]];
                            //if (k.IsNullableType())
                            //{
                            //    modelPropertyDescribe.PropertyType += "|| null";
                            //}
                        }
                    }
                }

              

                modelPropertyDescribes.Add(modelPropertyDescribe);
                //ssss.ModelPropertyDescribes
                //Console.WriteLine(k.PropertyType+"\t"+ k.Name);
            }
            modelDescribe.ModelPropertyDescribes = modelPropertyDescribes;

            ModelDescribes.Add(modelDescribe);
            return true;
        }

        public static string GetDescribe(Type type)
        {
            object[] objAttrs = type.GetCustomAttributes(typeof(DescribeAttribute), true);
            if (objAttrs.Length > 0)
            {
                DescribeAttribute attr = objAttrs[0] as DescribeAttribute;
                if (attr != null)
                {
                    return $"{attr.Describe}";
                }
            }
            return "";
        }
        public static string GetDescribe(MethodInfo type)
        {
            object[] objAttrs = type.GetCustomAttributes(typeof(DescribeAttribute), true);
            if (objAttrs.Length > 0)
            {
                DescribeAttribute attr = objAttrs[0] as DescribeAttribute;
                if (attr != null)
                {
                    return $"{attr.Describe}";
                }
            }
            return "";
        }
        
        public static string GetDescribe(ParameterInfo type)
        {
            object[] objAttrs = type.GetCustomAttributes(typeof(DescribeAttribute), true);
            if (objAttrs.Length > 0)
            {
                DescribeAttribute attr = objAttrs[0] as DescribeAttribute;
                if (attr != null)
                {
                    return $"{attr.Describe}";
                }
            }
            return "";
        }
        public static string GetDescribe(PropertyInfo type)
        {
            object[] objAttrs = type.GetCustomAttributes(typeof(DescribeAttribute), true);
            if (objAttrs.Length > 0)
            {
                DescribeAttribute attr = objAttrs[0] as DescribeAttribute;
                if (attr != null)
                {
                    return $"{attr.Describe}";
                }
            }
            return "";
        }

        private static bool IsPropertyTypeClass(Type type)
        {
            return type.IsClass;
        }
    }
}
